﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Data.MappingClasses;
using Model.Interfaces;
using Model.ModelClasses;
using Model.ModelEventArgs;
using Model.NotifyingCollections;
using Country = Data.MappingClasses.Country;
using Faculty = Data.MappingClasses.Faculty;
using Group = Data.MappingClasses.Group;
using Month = Model.ModelClasses.Month;
using Payment = Data.MappingClasses.Payment;
using School = Data.MappingClasses.School;
using Street = Data.MappingClasses.Street;
using Student = Data.MappingClasses.Student;
using Teacher = Data.MappingClasses.Teacher;
using Town = Data.MappingClasses.Town;

namespace Data
{
    public class DataDispatcher
    {
        private static MappingMasterDataContext _mappingMaster;
        private static DataDispatcher _dataDispatcher;

        private DataDispatcher()
        {
            _mappingMaster = new MappingMasterDataContext();
            LoadData();
        }

        public static DataDispatcher GetInstance()
        { return _dataDispatcher ?? (_dataDispatcher = new DataDispatcher()); }

        #region DataStore

        private void LoadData()
        {
            Teachers = new NotifyingModelList();
            Subjects = new NotifyingModelHashMap();
            Countreis = new NotifyingModelList();
            Groups = new NotifyingModelList();
            Students = new NotifyingModelList();
            Tests = new NotifyingModelHashMap();
            Schools = new NotifyingModelList();

            Console.WriteLine("Загрузка предметов..");
            #region load data of subjets
            foreach (var dbSubject in _mappingMaster.Subjects)
            {
                var modelSubject = new Model.ModelClasses.Subject {Name = dbSubject.nameSubject};
                dbSubject.PureModel = modelSubject;
                dbSubject.UpdateDataEvent += delegate
                                                 {
                                                     _mappingMaster.SubmitChanges();
                                                 };
                Subjects.Add(modelSubject);
            }
            #endregion
            Console.WriteLine("\nПредметы загружены");

            Console.WriteLine("Загрузка локейшонов..");
            #region load data of locations

            foreach (var dbCountry in _mappingMaster.Countries)
            {
                var modelCountry = new Model.ModelClasses.Country{Name = dbCountry.NameCountry, Towns = new NotifyingModelList()};

                foreach (var dbTown in dbCountry.Towns)
                {
                    var modelTown = new Model.ModelClasses.Town {Name = dbTown.nameTown, Country = modelCountry, Streets = new NotifyingModelList()};
                    foreach (var dbStreet in dbTown.Streets)
                    {
                        var modelStreet = new Model.ModelClasses.Street {Name = dbStreet.nameStreet, StreetType = dbStreet.StreetType.nameStreetType, Town = modelTown};
                        dbStreet.PureModel = modelStreet;
                        dbStreet.UpdateDataEvent += UpdateStreetDataEventHandler;
                        modelTown.Streets.Add(modelStreet);
                    }
                    dbTown.PureModel = modelTown;
                    dbTown.UpdateDataEvent += UpdateTownDataEventHandler;
                    dbTown.AddedStreetEvent += AddedStreetToTownEventHandler;
                    dbTown.RemovedStreetEvent += RemovedStreetFromTownEventHandler;
                    modelCountry.Towns.Add(modelTown);
                }

                dbCountry.PureModel = modelCountry;
                dbCountry.UpdateDataEvent += UpdateCountryDataEventHandler;
                dbCountry.AddedTownEvent += AddedTownToCountryEventHandler;
                dbCountry.RemovedTownEvent += RemovedTownFromCountryEventHandler;
                Countreis.Add(modelCountry);
            }
            #endregion
            Console.WriteLine("\nЛокейшоны загружены");

            Console.WriteLine("Загрузка школ..");
            #region load data of schools
            // доделать
            foreach (var dbSchool in _mappingMaster.Schools)
            {
                var modelSchool = new Model.ModelClasses.School
                                      {
                                          Name = dbSchool.nameSchool,
                                          AdditionalInformation = dbSchool.additionalInformation,
                                          ContactInformation = new OrganizationContactInformation
                                                                   {
                                                                       LandlinePhone = dbSchool.schoolMainPhoneNumber,
                                                                       AdditionalPhone = dbSchool.schoolAdditionalPhoneNumber,
                                                                       Email = dbSchool.email,
                                                                       Fax = dbSchool.fax,
                                                                       ContactPerson = dbSchool.contact,
                                                                       WebSite = dbSchool.webSite
                                                                   }
                                      };
                if (dbSchool.SchoolStatus != null)
                    modelSchool.Status = dbSchool.SchoolStatus.nameSchoolStatus;
                if(dbSchool.Address != null)
                {
                    School school = dbSchool;
                    modelSchool.Address = new OrganizationAddress
                                             { Building = dbSchool.Address.buildNumber };
                    if(dbSchool.Address.Street != null)
                        modelSchool.Address.Street = (IStreet) (from s in _mappingMaster.Streets where school.Address.Street == s select s.PureModel).First();

                    
                    dbSchool.Address.PureModel = (OrganizationAddress)modelSchool.Address;
                    dbSchool.Address.UpdateDataEvent += UpdateSchoolAddressDataEvent;
                }

                Schools.Add(modelSchool);
                dbSchool.PureModel = modelSchool;
                dbSchool.UpdateDataEvent += UpdateSchoolDataEventHandler;
            }
            Schools.AddedItemEvent += AddNewSchoolEventHandler;
            Schools.RemovedItemEvent += RemoveSchoolEventHandler;
            #endregion
            Console.WriteLine("\nШколы загружены");

            Console.WriteLine("Загрузка преподавателей..");
            #region Load data of teachers
            var teachers = _mappingMaster.Teachers;
            foreach (var dbTeacher in teachers)
            {
                var modelTeacher = new Model.ModelClasses.Teacher
                                       {
                                           FamilyName = dbTeacher.familyName,
                                           Name = dbTeacher.teacherName,
                                           FatherName = dbTeacher.fatherName,
                                           Birthday = dbTeacher.bornDate,
                                           IsCandidate = dbTeacher.IsCandidate,
                                           ContactInformation = new PersonContactInformation
                                                                    {
                                                                        LandlinePhone = dbTeacher.homePhone,
                                                                        MobilePhone = dbTeacher.mobilePhone,
                                                                        AdditionalPhone = dbTeacher.additionalPhone,
                                                                        Email = dbTeacher.email
                                                                    },
                                                                    
                                       };

                var tempTeacher = dbTeacher;
                modelTeacher.Subjects = new NotifyingModelHashMap();
                foreach (var subject in from ts in tempTeacher.TeacherSubjects where ts.Teacher == tempTeacher select ts.Subject.PureModel)
                    modelTeacher.Subjects.Add(subject); // привязываем этот предмет к преподавателю (уже на уровне объектов)

                modelTeacher.Subjects.AddedItemEvent += delegate(Object sender, ModelItemEventArgs modelItemEventArgs)
                                                            {
                                                                tempTeacher.TeacherSubjects.Add(new TeacherSubject{Teacher = tempTeacher, Subject = (from s in _mappingMaster.Subjects where s.PureModel == modelItemEventArgs.ModelItem select s).First()});
                                                                _mappingMaster.SubmitChanges();
                                                            };
                modelTeacher.Subjects.RemovedItemEvent += delegate(Object sender, ModelItemEventArgs modelItemEventArgs)
                                                            {
                                                                tempTeacher.TeacherSubjects.Remove((from ts in _mappingMaster.TeacherSubjects where (ts.Teacher == tempTeacher && ts.Subject.PureModel == modelItemEventArgs.ModelItem) select ts).First());
                                                                _mappingMaster.SubmitChanges();
                                                            };

                #region UpdateModelEventListener for ContactInformation of teacher (ModelTeacher)
                ((PersonContactInformation) modelTeacher.ContactInformation).UpdateModelEvent +=
                    delegate
                        {
                            //  <set new values>
                            tempTeacher.homePhone = modelTeacher.ContactInformation.LandlinePhone;
                            tempTeacher.mobilePhone = modelTeacher.ContactInformation.MobilePhone;
                            tempTeacher.additionalPhone = modelTeacher.ContactInformation.AdditionalPhone;
                            tempTeacher.email = modelTeacher.ContactInformation.Email;
                            //  </set new values>

                            _mappingMaster.SubmitChanges();     // submit changes to database
                        };
                #endregion
                #region UpdateModelEventListener for teacher (ModelTeacher)
                modelTeacher.UpdateModelEvent += delegate
                                                     {
                                                         //  <set new values>
                                                         tempTeacher.familyName = modelTeacher.FamilyName;
                                                         tempTeacher.teacherName = modelTeacher.Name;
                                                         tempTeacher.fatherName = modelTeacher.FatherName;
                                                         tempTeacher.bornDate = modelTeacher.Birthday;
                                                         tempTeacher.IsCandidate = modelTeacher.IsCandidate;
                                                         tempTeacher.homePhone =
                                                             modelTeacher.ContactInformation.LandlinePhone;
                                                         tempTeacher.mobilePhone =
                                                             modelTeacher.ContactInformation.MobilePhone;
                                                         tempTeacher.additionalPhone =
                                                             modelTeacher.ContactInformation.AdditionalPhone;
                                                         tempTeacher.email = modelTeacher.ContactInformation.Email;
                                                         //  </set new values>

                                                         _mappingMaster.SubmitChanges();    // submit changes to database
                                                     };
                #endregion

                tempTeacher.PureModel = modelTeacher;   // привязка объекта mapping-класса к объекту чистой модели
                Teachers.Add(modelTeacher);
            }
            Teachers.AddedItemEvent += AddNewTeacherEventHandler;
            Teachers.RemovedItemEvent += RemoveTeacherEventHandler;
            #endregion
            Console.WriteLine("\nПреподаватели загружены");

            #region Load data of tests
            foreach (var dbTest in _mappingMaster.Tests)
            {
                var modelTest = new Model.ModelClasses.Test
                                    {
                                        Date = dbTest.testDay,
                                        Name = dbTest.testName
                                    };
                Tests.Add(modelTest);
                dbTest.PureModel = modelTest;
                dbTest.UpdateDataEvent += UpdateTestEventHandler;
            }
            #endregion

            Console.WriteLine("Загрузка студентов..");
            #region Load data of students

            foreach (var dbStudent in _mappingMaster.Students)
            {
                var modelStudent = new Model.ModelClasses.Student
                                       {
                                           FamilyName = dbStudent.familyName,
                                           Name = dbStudent.studentName,
                                           FatherName = dbStudent.fatherName,
                                           Birthday = dbStudent.bornDate,
                                           ContactInformation = new PersonContactInformation
                                                                    {
                                                                        LandlinePhone = dbStudent.homePhone,
                                                                        MobilePhone = dbStudent.mobilePhone,
                                                                        AdditionalPhone = dbStudent.additionalPhone,
                                                                        Email = dbStudent.email
                                                                    },
                                           IsBenefit = dbStudent.isPrivilege,
                                           Groups = new NotifyingModelList(),
                                           Payments = new NotifyingModelHashMap(),
                                           TestResults = new NotifyingModelHashMap()
                                       };

                if (dbStudent.Address != null)
                {
                    modelStudent.Address = new HomeAddress
                                               {
                                                   Building = dbStudent.Address.buildNumber,
                                                   Flat = dbStudent.Address.room,
                                                   Street = (IStreet) dbStudent.Address.Street.PureModel
                                               };
                    dbStudent.Address.PureModel = (HomeAddress)modelStudent.Address;
                    dbStudent.Address.UpdateDataEvent += UpdateHomeAddressDataEventHandler;
                }
                
                foreach (var dbPayment in dbStudent.Payments)
                {
                    var modelPayment = new Model.ModelClasses.Payment
                                           { Sum = dbPayment.sum };
                    switch (dbPayment.Month.numberMonth)
                    {
                        case 1: modelPayment.Month = Month.January;
                            break;

                        case 2: modelPayment.Month = Month.February;
                            break;

                        case 3: modelPayment.Month = Month.March;
                            break;

                        case 4: modelPayment.Month = Month.April;
                            break;

                        case 5: modelPayment.Month = Month.May;
                            break;

                        case 6: modelPayment.Month = Month.June;
                            break;

                        case 7: modelPayment.Month = Month.July;
                            break;

                        case 8: modelPayment.Month = Month.August;
                            break;

                        case 9: modelPayment.Month = Month.September;
                            break;

                        case 10: modelPayment.Month = Month.October;
                            break;

                        case 11: modelPayment.Month = Month.November;
                            break;

                        case 12: modelPayment.Month = Month.December;
                            break;

                        default: throw new DateException();
                    }

                    modelStudent.Payments.Add(modelPayment);
                }

                modelStudent.Payments.AddedItemEvent += AddedPaymentToStudentEventHandler;
                modelStudent.Payments.RemovedItemEvent += RemovedPaymentFromStudentEventHandler;
                dbStudent.PureModel = modelStudent;
                dbStudent.UpdateDataEvent += UpdateStudentDataEventHandler;
                Students.Add(modelStudent);
            }
            Students.AddedItemEvent += AddNewStudentEventHandler;
            #endregion
            Console.WriteLine("\nСтуденты загружены");

            Console.WriteLine("Загрузка групп..");
            #region Load data of groups

            var groups = _mappingMaster.Groups;
            foreach (var dbGroup in groups)
            {
                var tempGroup = dbGroup;
                var modelGroup = new Model.ModelClasses.Group
                                     {
                                         Name = dbGroup.groupName,
                                         Subject = (ISubject)((from s in _mappingMaster.Subjects where s == tempGroup.TeacherSubject.Subject select s.PureModel).First()),
                                         Teacher = (Model.ModelClasses.Teacher)((from t in _mappingMaster.Teachers where t == tempGroup.TeacherSubject.Teacher select t).First().PureModel),
                                         BeginDate = tempGroup.beginDate,
                                         EndDate = tempGroup.endDate,
                                         Subdivision = tempGroup.Subdivision.nameSubdivision,
                                         Students = new NotifyingModelHashMap()
                                     };
                foreach (var studentGroup in tempGroup.StudentGroups)
                {
                    modelGroup.Students.Add(studentGroup.Student.PureModel);
                    if (studentGroup.Student.PureModel != null)
                        ((IStudent)studentGroup.Student.PureModel).Groups.Add(modelGroup);
                }
                modelGroup.Teacher = (ITeacher)(from t in _mappingMaster.Teachers where tempGroup.TeacherSubject.Teacher == t select t.PureModel).First();
                dbGroup.PureModel = modelGroup;
                dbGroup.UpdateDataEvent += UpdateGroupDataEventHandler;
                dbGroup.AddedStudentEvent += AddedStudentToGroupEventHandler;
                dbGroup.RemovedStudentEvent += RemovedStudentToGroupEventHandler;
                Groups.Add(modelGroup);
            }

            #endregion
            Console.WriteLine("\nГруппы загружены");
        }

        #region Listeners of update data
        private void RemovedStudentToGroupEventHandler(object sender, ModelItemEventArgs e)
        {
            ((Group)sender).StudentGroups.Remove((from s in _mappingMaster.StudentGroups where (s.Student.PureModel == e.ModelItem && s.Group == sender) select s).First());
            _mappingMaster.SubmitChanges();
        }

        private void AddedStudentToGroupEventHandler(object sender, ModelItemEventArgs e)
        {
            ((Group)sender).StudentGroups.Add(new StudentGroup { Group = ((Group)sender), Student = (from s in _mappingMaster.Students where s.PureModel == e.ModelItem select s).First() });
            _mappingMaster.SubmitChanges();
        }

        private void UpdateGroupDataEventHandler(object sender, EventArgs e)
        {
            ((Group)sender).TeacherSubject = (from ts in _mappingMaster.TeacherSubjects
                                              where
                                                  ts.Teacher.PureModel == ((IGroup)((Group)sender).PureModel).Teacher &&
                                                  ts.Subject.PureModel == ((ISubject)((Group)sender).PureModel)
                                              select ts).First();
            _mappingMaster.SubmitChanges();
        }
        // Обновление данных об улице
        private static void UpdateStreetDataEventHandler(object sender, EventArgs e)
        {
            ((Street)sender).Town = (from t in _mappingMaster.Towns where t.PureModel == ((IStreet)((Street)sender).PureModel).Town select t).First();
            ((Street)sender).StreetType = (from st in _mappingMaster.StreetTypes where st.nameStreetType == ((IStreet)((Street)sender).PureModel).StreetType select st).First();
            _mappingMaster.SubmitChanges();
        }

        // Обновление данных о городе
        private static void UpdateTownDataEventHandler(object sender, EventArgs e)
        {
            ((Town)sender).Country = (from c in _mappingMaster.Countries where c.PureModel == (((ITown)((Town)sender).PureModel).Country) select c).First();
            _mappingMaster.SubmitChanges();
        }

        // Добавление улицы в город (из модели)
        private static void AddedStreetToTownEventHandler(object sender, ModelItemEventArgs e)
        {
            ((Town)sender).Streets.Add((from s in _mappingMaster.Streets where s.PureModel == e.ModelItem select s).First());
            _mappingMaster.SubmitChanges();
        }

        private static void RemovedStreetFromTownEventHandler(object sender, ModelItemEventArgs e)
        {
            ((Town)sender).Streets.Remove((from s in _mappingMaster.Streets where s.PureModel == e.ModelItem select s).First());
            _mappingMaster.SubmitChanges();
        }

        private static void UpdateCountryDataEventHandler(object sender, EventArgs e)
        {
            _mappingMaster.SubmitChanges();
        }

        private static void AddedTownToCountryEventHandler(object sender, ModelItemEventArgs e)
        {
            ((Country)sender).Towns.Add((from t in _mappingMaster.Towns where t.PureModel == e.ModelItem select t).First());
            _mappingMaster.SubmitChanges();
        }

        private static void RemovedTownFromCountryEventHandler(object sender, ModelItemEventArgs e)
        {
            ((Country)sender).Towns.Remove((from t in _mappingMaster.Towns where t.PureModel == e.ModelItem select t).First());
            _mappingMaster.SubmitChanges();
        }

        private static void UpdateHomeAddressDataEventHandler(object sender, EventArgs e)
        {
            ((Address)sender).Street = (from s in _mappingMaster.Streets where s.PureModel == ((IAddress)((Address)sender).PureModel).Street select s).First();
            ((Address) sender).room = ((HomeAddress) ((Address) sender).PureModel).Flat;
            _mappingMaster.SubmitChanges();
        }

        private static void RemovedPaymentFromStudentEventHandler(object sender, ModelItemEventArgs e)
        {
            _mappingMaster.Payments.DeleteOnSubmit((from p in _mappingMaster.Payments where p.PureModel == e.ModelItem select p).First());
            _mappingMaster.SubmitChanges();
        }

        private static void AddedPaymentToStudentEventHandler(object sender, ModelItemEventArgs e)
        {
            var payment = new Payment { sum = ((IPayment)e.ModelItem).Sum };
            short number;
            switch (((IPayment)e.ModelItem).Month)
            {
                case Month.January: number = 1; break;
                case Month.February: number = 2; break;
                case Month.March: number = 3; break;
                case Month.April: number = 4; break;
                case Month.May: number = 5; break;
                case Month.June: number = 6; break;
                case Month.July: number = 7; break;
                case Month.August: number = 8; break;
                case Month.September: number = 9; break;
                case Month.October: number = 10; break;
                case Month.November: number = 11; break;
                case Month.December: number = 12; break;
                default: throw new DateException();
            }
            payment.Month = (from m in _mappingMaster.Months where m.numberMonth == number select m).First();
            _mappingMaster.Payments.InsertOnSubmit(payment);
            ((Student)sender).Payments.Add(payment);
            payment.PureModel = (Model.ModelClasses.Payment)e.ModelItem;
            payment.Student = ((Student)sender);

            _mappingMaster.SubmitChanges();
        }

        private static void UpdateStudentDataEventHandler(object sender, EventArgs e)
        {
            var student = ((Student)sender);
            student.Address = (from a in _mappingMaster.Addresses where a.PureModel == ((IStudent)student.PureModel).Address select a).First();
            student.School = (from s in _mappingMaster.Schools where s.PureModel == ((IStudent)student.PureModel).School select s).First();
            _mappingMaster.SubmitChanges();
        }

        private static void UpdateSchoolAddressDataEvent(object sender, EventArgs e)
        {
            ((Address)sender).Street = (from s in _mappingMaster.Streets where s.PureModel == ((IAddress)((Address)sender).PureModel).Street select s).First();
            _mappingMaster.SubmitChanges();
        }

        private static void UpdateSchoolDataEventHandler(object sender, EventArgs e)
        {
            ((School)sender).Address = (from a in _mappingMaster.Addresses where a.PureModel == ((ISchool)((School)sender).PureModel).Address select a).First();
            _mappingMaster.SubmitChanges();
        }

        private static void UpdateTestEventHandler(object sender, EventArgs e)
        {
            _mappingMaster.SubmitChanges();
        }
        #endregion

        private static void RemoveTeacherEventHandler(object sender, ModelItemEventArgs e)
        {
            throw new NotImplementedException();
        }

        private static void AddNewSchoolEventHandler(object sender, ModelItemEventArgs e)
        {
            var modelSchool = ((ISchool)e.ModelItem);
            var newSchool = new School
            {
                nameSchool = modelSchool.Name,
                Students = null,
                additionalInformation = modelSchool.AdditionalInformation,
                Address = null,
                contact = ((Model.ModelClasses.OrganizationContactInformation)modelSchool.ContactInformation).ContactPerson,
                email = ((Model.ModelClasses.OrganizationContactInformation)modelSchool.ContactInformation).Email,
                fax = ((Model.ModelClasses.OrganizationContactInformation)modelSchool.ContactInformation).Fax,
                schoolAdditionalPhoneNumber = ((Model.ModelClasses.OrganizationContactInformation)modelSchool.ContactInformation).AdditionalPhone,
                schoolMainPhoneNumber = ((Model.ModelClasses.OrganizationContactInformation)modelSchool.ContactInformation).LandlinePhone,
                webSite = ((Model.ModelClasses.OrganizationContactInformation)modelSchool.ContactInformation).WebSite,
                SchoolStatus = new SchoolStatus { nameSchoolStatus = modelSchool.Status},
            };



            _mappingMaster.Schools.InsertOnSubmit(newSchool);
            _mappingMaster.SubmitChanges();
        }

        private static void RemoveSchoolEventHandler(object sender, ModelItemEventArgs e)
        {

        }


        private static void AddNewStudentEventHandler(object sender, ModelItemEventArgs e)
        {
            var modelStudent = ((IStudent)e.ModelItem);
            Address newStudentAddress = new Address();
            
            //newStudentAddress.buildNumber = modelStudent.Address.Building;
            

            var newStudent = new Student
            {
                additionalPhone = modelStudent.ContactInformation.AdditionalPhone,
                email = modelStudent.ContactInformation.Email,
                homePhone = modelStudent.ContactInformation.LandlinePhone,
                mobilePhone = modelStudent.ContactInformation.MobilePhone,
                Address = null,
                bornDate = modelStudent.Birthday,
                Faculty = null,
                familyName = modelStudent.FamilyName,
                fatherName = modelStudent.FatherName,
                studentName = modelStudent.Name               
            };

            _mappingMaster.Students.InsertOnSubmit(newStudent);
            _mappingMaster.SubmitChanges();
        }


        private static void AddNewTeacherEventHandler(object sender, ModelItemEventArgs e)
        {
            var modelTeacher = ((ITeacher)e.ModelItem);
            var newTeacher = new Teacher
            {
                familyName = modelTeacher.FamilyName,
                fatherName = modelTeacher.FatherName,
                teacherName = modelTeacher.Name,
                bornDate = modelTeacher.Birthday,
                IsCandidate = modelTeacher.IsCandidate,
                homePhone = modelTeacher.ContactInformation.LandlinePhone,
                mobilePhone = modelTeacher.ContactInformation.MobilePhone,
                additionalPhone = modelTeacher.ContactInformation.AdditionalPhone,
                email = modelTeacher.ContactInformation.Email
            };

            if(modelTeacher.Subjects != null && modelTeacher.Subjects.Count > 0)
            foreach (var subject in modelTeacher.Subjects)
            {
                var tempSubject = subject;
                var dbSubject = (from s in _mappingMaster.Subjects where s.PureModel == tempSubject select s).First();
                newTeacher.TeacherSubjects.Add(new TeacherSubject { Subject = dbSubject, Teacher = newTeacher});
            }

            _mappingMaster.Teachers.InsertOnSubmit(newTeacher);
            _mappingMaster.SubmitChanges();
        }

        public NotifyingModelList Teachers { get; private set; }

        public NotifyingModelList Groups { get; private set; }

        public NotifyingModelHashMap Subjects { get; private set; }

        public NotifyingModelHashMap Tests { get; set; }

        public NotifyingModelList Countreis { get; private set; }

        public NotifyingModelList Students { get; set; }

        public NotifyingModelList Schools { get; set; }

        #endregion

        public bool TryLogin(string username, string userpass)
        {
            var query = from s in _mappingMaster.GetTable<User>()
                        where ((s.userName == username) && (s.userPassword == userpass))
                        select new {s.userName};
            return query.Count() > 0;
        }

        public void AddStreetType(string streetType)
        {
            _mappingMaster.StreetTypes.InsertOnSubmit(new StreetType {nameStreetType = streetType});
            _mappingMaster.SubmitChanges();
        }

        public ArrayList GetAllStreetTypes()
        {
            var allStreetTypes = from s in _mappingMaster.GetTable<StreetType>()
                                 select s;
            var result = new ArrayList(allStreetTypes.Count());

            foreach (var allStreetType in allStreetTypes)
                result.Add(allStreetType);

            return result;
        }

        public List<IFaculty> GetAllFculties()
        {
            var allFacuties = from s in _mappingMaster.GetTable<Faculty>()
                              select s;
            var result = new List<IFaculty>(allFacuties.Count());

            foreach (var faculty in allFacuties)
            {
                var pureModelFaculty = faculty.PureModel;
                faculty.UpdateDataEvent += UpdateDataEventHandler;
                result.Add(((IFaculty)pureModelFaculty));
            }
            return result;
        }

        /*
        public List<ICountry> GetAllCountries()
        {
            var allCountriesFromDb = _mappingMaster.Countries;
            foreach (var country in allCountriesFromDb)
            {
                country.RemovedTownEvent += delegate(Object sender, ModelItemEventArgs townEventArgs)
                                               {
                                                   var townToDelete = from t in _mappingMaster.Towns
                                                                      where
                                                                          t.Country == sender &&
                                                                          t.nameTown == townEventArgs.Body
                                                                      select t;
                                                   _mappingMaster.Towns.DeleteOnSubmit(townToDelete.First());
                                                   _mappingMaster.SubmitChanges();
                                               };
            }

            var result = new List<ICountry>(allCountriesFromDb.Count());
            foreach (var country in allCountriesFromDb)
            {
                var pureModelCountry = country.PureModel;
                country.UpdateDataEvent += UpdateDataEventHandler;
                result.Add(((ICountry)pureModelCountry));
            }
            return result;
        }
         * */

        private static void UpdateDataEventHandler(object sender, EventArgs e)
        { _mappingMaster.SubmitChanges(); }

        public void WriteNewCountryInfo(ICountry country)
        {
            var newCountry = new Country{NameCountry = country.Name};

            foreach (var town in country.Towns)
            {
                newCountry.Towns.Add(new Town{nameTown = ((ITown)town).Name});
            }
            _mappingMaster.Countries.InsertOnSubmit(newCountry);
            _mappingMaster.SubmitChanges();
        }

        public List<IStudent> GetAllStudents()
        {
            var allStudentsFromDb = from s in _mappingMaster.GetTable<Student>() select s;

            var result = new List<IStudent>();
            
            foreach (var studentFromDb in allStudentsFromDb)
            {
                var student = new Model.ModelClasses.Student
                                  {
                                      Name = studentFromDb.studentName,
                                      FamilyName = studentFromDb.familyName,
                                      FatherName = studentFromDb.fatherName,
                                      ContactInformation = new PersonContactInformation
                                                               {
                                                                   LandlinePhone = studentFromDb.homePhone,
                                                                   MobilePhone = studentFromDb.mobilePhone,
                                                                   AdditionalPhone = studentFromDb.additionalPhone,
                                                                   Email = studentFromDb.email
                                                               }

                                  };
                if (studentFromDb.Faculty != null)
                    student.Faculty = new Model.ModelClasses.Faculty
                                          {
                                              Code = studentFromDb.Faculty.FacultyShortName,
                                              Name = studentFromDb.Faculty.FacultyName
                                          };
                if (studentFromDb.School != null)
                    student.School = new Model.ModelClasses.School {Name = studentFromDb.School.nameSchool};
                result.Add(student);
            }
            return result;
        }

        public void Test()
        {
            var tempTeachers = (from teacher in _mappingMaster.Teachers where teacher.familyName == "Белан" select teacher);
//            if(tempTeachers.Count() > 0)
                Console.WriteLine(((Model.ModelClasses.Teacher)tempTeachers.FirstOrDefault().PureModel).FullName);
        }

        public void WriteNewStudentInfo(Model.ModelClasses.Student student)
        {
            var newStudent = new Student
            {
                bornDate = student.Birthday,
                familyName = student.FamilyName,
                studentName = student.FullName,
                fatherName = student.FatherName,
                mobilePhone = null,
                additionalPhone = null,
                email = null,
                refAddress = null,
                refSchool = null
            };


            /*var newStudent = new Student
                                 {
                                     idStudent = 2,
                                     bornDate = new DateTime(1989, 3, 26),
                                     familyName = "Ivanov",
                                     studentName = "Ivan",
                                     fatherName = "Petrovich",
                                     mobilePhone = "0956875326",
                                     isPrivilege = false,
                                     refAddress = null
                                 };
//            newStudent.refFaculty = null;
//            newStudent.refSchool = null*/
            _mappingMaster.Students.InsertOnSubmit(newStudent);
            _mappingMaster.SubmitChanges();
        }
    }
}